package com.yunti.springboot.service.impl;


import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.yunti.springboot.mapper.*;
import com.yunti.springboot.po.*;
import com.yunti.springboot.service.ExamService;
import com.yunti.springboot.util.SemesterUtil;
import com.yunti.springboot.vo.Result;
import com.yunti.springboot.vo.req.GetAllExamSubByClassReq;
import com.yunti.springboot.vo.res.ExamSubInfoRes;
import com.yunti.springboot.vo.res.SubjectWithCompletionRateRes;
import org.springframework.beans.BeanUtils;
import org.springframework.stereotype.Service;

import javax.annotation.Resource;
import java.util.*;
import java.util.stream.Collectors;

@Service
public class ExamServiceImpl implements ExamService {

    @Resource
    private ElectiveSubMapper electiveSubMapper;

    @Resource
    private StudentMapper studentMapper;

    @Resource
    private OptionMapper optionMapper;

    @Resource
    private SubjectMapper subjectMapper;

    @Resource
    private ScoreMapper scoreMapper;

    @Override
    public Result getAllExamSubByClass(GetAllExamSubByClassReq getAllExamSubByClassReq) {
        Integer stuCount = 0;
        LambdaQueryWrapper<Student> studentLambdaQueryWrapper = new LambdaQueryWrapper<>();
        studentLambdaQueryWrapper.eq(Student::getClassId, getAllExamSubByClassReq.getClassId());
        List<Student> studentList = studentMapper.selectList(studentLambdaQueryWrapper);
        List<Integer> stuIdList = studentList.stream().map(Student::getId).collect(Collectors.toList());
        stuCount = studentList.size();

        ExamSubInfoRes examSubInfoRes = new ExamSubInfoRes();
        examSubInfoRes.setStuCount(stuCount);

        //如果查询学期为null,则表明查询当前学期
        if (getAllExamSubByClassReq.getSemester() == null) {
            getAllExamSubByClassReq.setSemester(SemesterUtil.getNowSemesterByYear(getAllExamSubByClassReq.getYear()));
        }

        //得到该学期考试科目
        LambdaQueryWrapper<ElectiveSub> electiveSubLambdaQueryWrapper = new LambdaQueryWrapper<>();
        electiveSubLambdaQueryWrapper.eq(ElectiveSub::getSemester, getAllExamSubByClassReq.getSemester());
        List<ElectiveSub> electiveSubList = electiveSubMapper.selectList(electiveSubLambdaQueryWrapper);
        List<Integer> subIdList = electiveSubList.stream().map(ElectiveSub::getSubId).distinct().collect(Collectors.toList());

        List<Integer> allElectiveSubIdList = electiveSubList.stream().map(ElectiveSub::getId).collect(Collectors.toList());
        if(allElectiveSubIdList.size() == 0){
            return Result.success(examSubInfoRes);
        }

        //得到选考项的id
        List<Integer> selectSubElectiveIdList = electiveSubList.stream().filter(e -> e.getSubId() == -1).map(ElectiveSub::getId).collect(Collectors.toList());
        Map<Integer, List<Option>> optionMap = new LinkedHashMap<>();
        if (selectSubElectiveIdList.size() != 0 && stuIdList.size() != 0) {
            //得到考生所选考的科目
            LambdaQueryWrapper<Option> optionLambdaQueryWrapper = new LambdaQueryWrapper<>();
            optionLambdaQueryWrapper.in(Option::getElectiveSubId, selectSubElectiveIdList);
            optionLambdaQueryWrapper.in(Option::getStuId, stuIdList);
            List<Option> optionList = optionMapper.selectList(optionLambdaQueryWrapper);
            List<Integer> selectSubIdList = optionList.stream().map(Option::getSubId).distinct().collect(Collectors.toList());
            subIdList.addAll(selectSubIdList);
            optionMap = optionList.stream().collect(Collectors.groupingBy(Option::getSubId));
        }


        LambdaQueryWrapper<Subject> subjectMapperLambdaQueryWrapper = new LambdaQueryWrapper<>();
        subjectMapperLambdaQueryWrapper.in(Subject::getId, subIdList);
        List<Subject> subjectList = subjectMapper.selectList(subjectMapperLambdaQueryWrapper);


        List<Score> scoreList = new ArrayList<>();
        Map<Integer, Set<String>> scoreMap = new LinkedHashMap<>();
        if (stuIdList.size() != 0) {
            LambdaQueryWrapper<Score> scoreLambdaQueryWrapper = new LambdaQueryWrapper<>();
            scoreLambdaQueryWrapper.in(Score::getSubId, subIdList);
            scoreLambdaQueryWrapper.in(Score::getStuId, stuIdList);
            scoreLambdaQueryWrapper.in(Score::getElectiveId, allElectiveSubIdList);
            scoreList = scoreMapper.selectList(scoreLambdaQueryWrapper);
            for (int i = 0; i < scoreList.size(); i++) {
                if(scoreMap.get(scoreList.get(i).getSubId()) == null){
                    Set<String> stringSet = new HashSet<>();
                    stringSet.add(scoreList.get(i).getStuId() + "-" + scoreList.get(i).getSubId() + "-" + scoreList.get(i).getElectiveId());
                    scoreMap.put(scoreList.get(i).getSubId(),stringSet);
                }else{
                    Set<String> stringSet =  scoreMap.get(scoreList.get(i).getSubId());
                    stringSet.add(scoreList.get(i).getStuId() + "-" + scoreList.get(i).getSubId() + "-" + scoreList.get(i).getElectiveId());
                }
            }

//            scoreMap = scoreList.stream().collect(Collectors.groupingBy(Score::getSubId));

        }


        List<SubjectWithCompletionRateRes> subjectWithCompletionRateResList = new ArrayList<>();
        for (int i = 0; i < subjectList.size(); i++) {
            SubjectWithCompletionRateRes subjectWithCompletionRateRes = new SubjectWithCompletionRateRes();
            BeanUtils.copyProperties(subjectList.get(i), subjectWithCompletionRateRes);
            if (subjectWithCompletionRateRes.getType() == 1 || subjectWithCompletionRateRes.getType() == 4) {
                subjectWithCompletionRateRes.setTotalCount(stuCount);
            } else {
                if (optionMap.get(subjectWithCompletionRateRes.getId()) != null) {
                    subjectWithCompletionRateRes.setTotalCount(optionMap.get(subjectWithCompletionRateRes.getId()).size());
                }
            }
            if (scoreMap.get(subjectWithCompletionRateRes.getId()) != null) {
                subjectWithCompletionRateRes.setCompleteCount(scoreMap.get(subjectWithCompletionRateRes.getId()).size());
            }
            subjectWithCompletionRateResList.add(subjectWithCompletionRateRes);
        }
        examSubInfoRes.setSubjectWithCompletionRateResList(subjectWithCompletionRateResList);

        return Result.success(examSubInfoRes);
    }
}
